
----------------------------------------------------------------
--- Copyright：  迷你玩-海马
--- Description：数据缓存服务器 附加函数库

---- 一些接口与业务强相关，定制化的功能都写在这里

----------------------------------------------------------------




local assert     = assert
local require    = require
local bit        = bit
local coroutine  = coroutine
local debug      = debug
local io         = io
local pairs      = pairs
local ipairs     = ipairs
local math       = math
local os         = os
local print      = print
local pcall      = pcall
local xpcall     = xpcall
local rawget     = rawget
local rawset     = rawset
local select     = select
local string     = string
local table      = table
local tonumber   = tonumber
local tostring	 = tostring
local error      = error
local type       = type
local unpack     = unpack
local setmetatable = setmetatable
local getmetatable = getmetatable
local ngx = ngx

local string_char  = string.char
local string_sub   = string.sub
local string_byte  = string.byte
local string_gsub  = string.gsub
local string_find  = string.find
local string_upper = string.upper

local math_fmod   = math.fmod
local math_floor  = math.floor
local math_pow    = math.pow
local math_abs    = math.abs


local uu           = require( "modules.commhm.utils" )
local log          = require( "modules.commhm.log" )
local ns_time      = require( "modules.commhm.time" )
local ns_network   = require( "modules.commhm.network" )
local ns_http      = require( "modules.commhm.resty.http" )

local ns_const_vars  = require("modules.commhm.const_vars")

local ns_config       = require( "modules.data_cache.data_cache_config" )
local gg              = require( "modules.data_cache.data_cache_shm_gg" )
local ns_auth_checker = require( "modules.data_cache.auth_checker" )


local NGX_NULL  = "not_found"                  --ngx.null


local FOO = {
	_VERSION = '0.12.1',
	worker_id = ngx.worker.id(),
};



-- 写入数据中的一个子项(path),目前最大支持1层 （path是一个字符串，中间可以有 '.' 分割符号）
FOO.save_by_path = function()

	local args_   = ngx.ctx.m_params

	local name_   = args_.name      --shm name: ma map posting
	local key_    = args_.key
	local hash_   = args_.hash
	local select_ = gg.private_get_select()

	local path_   =  args_.path

	if  not ( name_ and select_ and key_ and hash_ and path_ ) then
		--uu.return_string( "PARAM_ERROR", ns_const_vars.ERROR_CODE.PARAM )
		uu.return_table( { ret=ns_const_vars.ERROR_CODE.PARAM, msg="PARAM_ERROR" } )
		return
	end


	-- 获得value
	local len_
	local value_
	if  args_.value then
		value_ = args_.value   --一定是string
		-- haima test
		if  ns_config.debug == 1 then
			if  value_ == 'test_json1' then
				value_ = '{ "a":1, "b":2, "c":3 }'
			elseif  value_ == 'test_json2' then
				value_ = '{ "a":77, "b":88, "c":99 }'
			elseif value_ == 'test_json3' then
				value_ = '{ "a":111, "b":222, "c":333 }'
			end
		end
	elseif args_.post_value then
		--post里的所有内容都是value, post_value是长度
		len_ = tonumber(args_.post_value) or 0
		ngx.req.read_body();
		value_ = ngx.req.get_body_data()
	end

	if  len_ and (len_ <= 0) then
		--uu.return_string( "NO_V_LEN0", ns_const_vars.ERROR_CODE.PARAM )
		uu.return_table( { ret=ns_const_vars.ERROR_CODE.PARAM, msg="NO_V_LEN0" } )
		return
	end


	---if decode base64
	if  args_.isbase64 == '1' then
		local value_64_ = ngx.decode_base64(value_)
		if  value_64_ then
			log.day_list_simple( "dc_shm", "base64_decode_ok", #value_, #value_64_ )
			value_ = value_64_
		else
			log.day_list_simple( "dc_shm", "error_base64", key_, hash_, select_, value_ )
			--uu.return_string( "ERROR_BASE64", ns_const_vars.ERROR_CODE.PARAM )
			uu.return_table( { ret=ns_const_vars.ERROR_CODE.PARAM, msg="VALUE_DECODE_BASE64" } )
			return
		end
	end

	-- 结构体一定是json
	local v_table_ = uu.json2table( value_ )
	if  not v_table_ then
		--uu.return_string( "PARAM_ERROR", ns_const_vars.ERROR_CODE.PARAM )
		uu.return_table( { ret=ns_const_vars.ERROR_CODE.PARAM, msg="VALUE_NOT_JSON" } )
		return
	end


	-- 1 read data
	local ret_string_, ret_table_
	local shm_mgr_ = gg.shmMgrDcList[ name_ ]
	if  not shm_mgr_ then
		--uu.return_string( "PARAM_ERROR", ns_const_vars.ERROR_CODE.PARAM )
		uu.return_table( { ret=ns_const_vars.ERROR_CODE.PARAM, msg="NAME_NOT_CONFIG" } )
		log.error( "conf not exit=" .. name_ )
		return
	end

	ret_string_ = shm_mgr_:API_shm_read( select_, key_, hash_, nil, gg.error_exit, args_.read_only )
	if  ret_string_ then
		log.debug( "API_shm_read=" .. ret_string_ )

		if  ret_string_ == NGX_NULL then
			ret_table_ = {}   ---为空初始化
		else
			---解析结构体
			ret_table_ = uu.json2table( ret_string_ )
			if  not (type( ret_table_ ) == 'table') then
				--uu.return_string( "READ_VALUE_NOT_JSON", ns_const_vars.ERROR_CODE.PARAM )
				uu.return_table( { ret=ns_const_vars.ERROR_CODE.PARAM, msg="READ_RET_NOT_JSON", string=ret_string_ } )
				log.error( "conf not exit=" .. name_ )
				return
			end
		end

		-- 2 change path value
		ret_table_[ path_ ] = v_table_

		-- 3 save data
		local et_  = args_.et        --expire_time
		local string_pack_ = uu.table2json( ret_table_ )
		local ret_ = shm_mgr_:API_shm_save( select_, key_, hash_, string_pack_, et_,
				gg.error_exit, args_.read_only )
		--uu.return_string( ret_ or "" )
		uu.return_table( { ret=0, msg=ret_ } )
	else
		--uu.return_string( "ERROR_API_shm_read", ns_const_vars.ERROR_CODE.Internal_Server_Error )
		uu.return_table( { ret=ns_const_vars.ERROR_CODE.Internal_Server_Error, msg="READ_FAIL" } )
		log.error( "conf not exit=" .. name_ )
	end

end


return FOO;
